"""
Populates database with stocks.
"""

import datetime
import time
import numpy
from system import infogetter
from misc import timedata
import agent
import system.navalasystem as na
import misc.quoteperiod as qp

class Populator(agent.Agent):
    # infogetter.InfoGetter instance
    infoGetter = None
    # Number of days of date interval to probe for quotes
    numDays = 45
    # Minimum sanity to insert stock in database. Sanity is a value within the
    # [0, 1] interval, calculated as the n_q/n_max, where n_c is the number of
    # quotes of current stock, and n_max is the maximum number of quotes among
    # all stocks. 
    sanityThreshold = 0.7
    # Unwanted markets
    unwantedMarkets = ("OPCAO", "FRACIONARIO", "OPF", "OPD")
    # Symbols pattern to match
    symbolPattern = ""
    
    def Cycle_(self):
        state = self.GetState()
        if state == agent.AS_INITIAL:
            self.Go()
            self.SetState(agent.AS_END)
    
    def Go(self):
        db = na.vala.db
        
        today = datetime.date.today()
        interval  = datetime.timedelta(self.numDays)
        pastday = today-interval
        s_today = today.strftime('%Y-%m-%d')
        s_pastday = pastday.strftime('%Y-%m-%d')
        a = self.infoGetter.GetSymbols(self.symbolPattern)
        len_a = len(a)
        sanities = numpy.zeros(len_a) # to record the sanity index of each stock

        self.logger.info("Number of symbols read: %d" % len_a)

        i = 0
        ii = 0
        for item in a:
            if item.market in self.unwantedMarkets:
                self.logger.info("Skipping symbol %s (unwanted market: \"%s\")" 
                                 % (item.symbol, item.market))
            else:
                b = self.infoGetter.GetHistory(item.symbol, s_pastday, s_today, \
                    qp.daily)
                sanities[i] = len(b.timestamp)
                self.logger.info("%s: Number of quotes: %d" % (item.GetName(), len(b)))
            i += 1
            ii += 1
            if ii >= 100:
                print "%4.2f%%" % (float(i)/len_a*100,)
                ii = 0
                
        sanities = sanities/numpy.max(sanities) # Maximum value will be 1
        bIn = sanities >= self.sanityThreshold
        numIn = sum(bIn == True)
        self.logger.info("--- Number of stocks to insert: %d ---" % numIn)
        for i, item in enumerate(a):
            self.logger.info("%4d: %s" % (i, item.GetName()))
        
        numInserted = 0
        for flag, item, sanity in zip(bIn, a, sanities):
            if flag:
                result = db.ReadWhere("/stock", "name == '%s'" % 
                                      item.GetName())
                if len(result) == 0:
                    db.stock_Insert(item.supermarket, item.market, item.symbol, item.GetName(), item.description, sanity)
                    numInserted += 1
        self.logger.info("--- Number of stocks inserted: %d ---" % numInserted)


class PopulatorError(Exception):
    pass
